package com.fs.sys.service;

import com.fs.sys.bean.dto.AppDTO;
import com.fs.sys.entityservice.AppEntityService;
import com.fs.common.AppConstants;
import com.fs.common.base.bean.dto.BaseDTO;
import com.fs.sys.bean.dto.TenantAppDTO;
import com.fs.sys.bean.enums.AppUseLimitType;
import com.fs.sys.bean.resp.TenantAppResp;
import com.fs.sys.entityservice.TenantAppEntityService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 租户应用服务
 *
 * @author LiuQi 2025/6/14-11:03
 * @version V1.0
 **/
@Service
public class TenantAppService {
    @Autowired
    private TenantAppEntityService tenantAppEntityService;

    @Autowired
    private AppEntityService appEntityService;

    /**
     * 查询租户可访问应用列表
     * @param tenantId 租户id
     * @return 租户可访问的应用列表
     */
    public List<AppDTO> findTenantCanVisitApps(String tenantId) {
        // 包括公共的应用、租户自己创建的应用及分配给租户的应用
        List<String> tenantDispatchedAppIds = tenantAppEntityService.findByTenant(tenantId)
                .stream()
                // 已过期的不算
                .filter(item -> !item.expired())
                .map(TenantAppDTO::getAppId)
                .toList();
        return appEntityService.queryBuilder()
                .eq("status", 1)
                .query()
                .stream()
                .filter(app -> {
                    if (app.getUseLimitType() == AppUseLimitType.PUBLIC) {
                        return true;
                    } else if (app.getTenantId().equals(tenantId)) {
                        return true;
                    }

                    return tenantDispatchedAppIds.contains(app.getId());
                }).toList();
    }

    /**
     * 查找租户已分配应用列表
     * 不包含租户自己创建的应用
     */
    public List<TenantAppResp> getTenantDispatchedApps(String tenantId) {
        List<TenantAppDTO> list = tenantAppEntityService.findByTenant(tenantId);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>(16);
        }
        List<String> appIds = list.stream()
                .map(TenantAppDTO::getAppId)
                .toList();
        Map<String, AppDTO> appMap = appEntityService.findByIds(appIds)
                .stream()
                .collect(Collectors.toMap(BaseDTO::getId, n -> n));
        return list.stream()
                .map(item -> {
                    TenantAppResp resp = new TenantAppResp();
                    BeanUtils.copyProperties(item, resp);
                    resp.setApp(appMap.get(item.getAppId()));
                    return resp;
                }).toList();
    }

    /**
     * 查找租户未分配应用列表
     * @param tenantId 租户id
     * @return 租户未分配应用列表
     */
    public List<AppDTO> findNotDispatched(String tenantId) {
        List<AppDTO> apps = appEntityService.queryBuilder()
                // 查超管维护的并且是auth类型的应用
                .eq("tenant_id", AppConstants.SUPER_TENANT)
                .eq("use_limit_type", AppUseLimitType.AUTH)
                .query();

        // 查找已分配的应用列表
        List<String> dispatchedAppIds = tenantAppEntityService.findByTenant(tenantId)
                .stream()
                .map(TenantAppDTO::getAppId)
                .toList();

        return apps.stream().filter(app -> !dispatchedAppIds.contains(app.getId())).toList();
    }

    /**
     * 分配租户应用
     * @param tenantId 租户id
     * @param appIds 应用id列表
     */
    public void add(String tenantId, List<String> appIds, LocalDate expireDate) {
        if (CollectionUtils.isEmpty(appIds)) {
            return;
        }

        List<TenantAppDTO> list = appIds.stream().map(appId -> {
            TenantAppDTO tenantAppDTO = new TenantAppDTO();
            tenantAppDTO.setAppId(appId);
            tenantAppDTO.setTenantId(tenantId);
            tenantAppDTO.setExpireDate(expireDate);
            return tenantAppDTO;
        }).toList();
        tenantAppEntityService.insert(list);
    }
}
